查看原文
其他

DB账号防泄密,请立刻为数据库加把锁!(附演示视频)

2017-03-24 贺春旸 DBAplus社群


作者介绍

贺春旸普惠金融MySQL专家,《MySQL管理之道》第一版、第二版作者。曾任职于中国移动飞信、机锋安卓市场,拥有丰富的数据库管理经验。目前致力于MySQL、Linux等开源技术的研究。


一、技术实施背景


区别于传统型互联网公司,互联网金融公司对数据安全性要求较高。目前我们是用MariaDB的多源复制技术把线上的核心业务库同步过来,聚集成一个大的汇总库提供给数据模型部门分析数据,以及开发人员排查问题等。


由于业务日渐壮大,拥有DB账号的人数也越来越多,这里就存在着一个安全隐患:周末我们在咖啡厅连接数据库排查问题,如果被别人用嗅探工具监听,那么发生数据泄密的几率就会大大增加。


为了防止这种情况,我们就需要用SSL(Secure Sockets Layer 安全套接层协议)来实现客户端与服务器端之间的通信是进行加密的,没有了密钥,就无法解开加密的数据,从而保证通信的私密性。


二、安全连接概述


默认情况下客户端(PHP/JAVA等)连接MySQL/MariaDB传输数据是不加密的,可以通过下面的命令来验证这一点:


MariaDB [(none)]> SHOW VARIABLES LIKE 'have_ssl';

+---------------+----------+

| Variable_name | Value    |

+---------------+----------+

| have_ssl      |   DISABLED |

+---------------+----------+

1 row in set (0.00 sec)


如果服务器支持安全连接,则值将设置为YES。如果未编译TLS模块,则值将设置为NO。DISABLED表示服务器已使用TLS模块进行编译,但未使用TLS模块启动,这通常是缺省情况。


你可以验证下TLS库是否动态链接,例:


# ldd `which mysqld` | grep ssl

        libssl.so.10 =>   /usr/lib64/libssl.so.10 (0x00007fd6a7bce000)


三、设置MariaDB SSL和安全客户端连接


SSL是利用密钥的加密技术(RSA)来作为用户端与服务器端在传送数据时的加密通讯协议。这里我们用通俗的语言来解释下这几个文件的含义:ca-cert.pem就是房产证,server-cert.pem就是门锁,client-key.pem就是钥匙。当你的证件齐全时,进到你家里才是合法的。



Step 1 - 升级OpenSSL


由于Centos6.8自带的OpenSSL版本太低,其自身的漏洞可能会带来安全隐患,故这里升级到最新版。


# wget https://www.openssl.org/source/openssl-1.1.0e.tar.gz

# cd openssl-1.1.0e

# ./config

# make;make install

# ln -s /usr/local/lib64/libssl.so.1.1   /usr/lib64/libssl.so.1.1

# ln -s /usr/local/lib64/libcrypto.so.1.1   /usr/lib64/libcrypto.so.1.1

# mv /usr/bin/openssl /usr/bin/openssl_bak

# mv /usr/include/openssl /usr/include/openssl_bak

# ln -s /usr/local/bin/openssl /usr/bin/openssl

# ln -s /usr/local/include/openssl /usr/include/openssl


默认是安装在/usr/local/bin/目录下。


Step 2 - 创建CA证书


# mkdir -p /etc/mysql/ssl/

# cd /etc/mysql/ssl/


1、创建CA证书颁发机构的密钥文件


# sudo /usr/local/bin/openssl genrsa 2048 > ca-key.pem



2、创建CA证书颁发机构的证书文件


# sudo /usr/local/bin/openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem



注:Common Name (e.g. server FQDN or YOUR name) []:这里的名字不能有重复的,分表设置为:


CA common Name : MariaDB admin

Server common Name: MariaDB server

Client common Name: MariaDB client


Step 3 - 创建server端证书


1、创建server端密钥文件


# sudo /usr/local/bin/openssl req -newkey rsa:2048 -days 365000 -nodes -keyout server-key.pem -out server-req.pem



2、创建server端RSA密钥文件


# sudo /usr/local/bin/openssl rsa -in server-key.pem -out server-key.pem



3、创建server端证书



Step 4 - 创建client端证书


创建client端密钥文件

# sudo /usr/local/bin/openssl req -newkey rsa:2048 -days 7 -nodes

-keyout client-key.pem -out client-req.pem



注:-days 7是密钥有效期为7天,过期后失效。


2、创建client端RSA密钥文件


# sudo /usr/local/bin/openssl rsa -in client-key.pem -out client-key.pem



3、创建client端证书


#sudo /usr/local/bin/openssl x509 -req -in client-req.pem -days 7 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem



注:-days 7是证书有效期为7天,过期后失效。


Step 5 - 如何验证证书?


#sudo /usr/local/bin/openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem



注:如上图两个OK,代表成功。


Step 6 - MariaDB服务端开启SSL加密


1、编辑my.cnf添加如下参数


ssl

ssl-ca=/etc/mysql/ssl/ca-cert.pem

ssl-cert=/etc/mysql/ssl/server-cert.pem

ssl-key=/etc/mysql/ssl/server-key.pem


注:在[mysqld]下面添加。


2、重启mysqld进程


# mysqladmin shutdown

# mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &


3、输入show variables like '%ssl%';查看是否生效,如出现下图的两个YES,代表成功开启SSL



Step 7 - MariaDB客户端使用SSL加密连接


1、创建SSL账号权限


> GRANT SELECT ON *.* TO 'demo'@'%' IDENTIFIED BY ‘demo’   REQUIRE SSL;


2、mysql命令行登录连接


将ca-cert.pem文件、client-cert.pem文件、client-key.pem拷贝到客户端目录下,输入下面的命令进行登录连接:


# cd /etc/mysql/ssl

# mysql --ssl-ca=ca-cert.pem --ssl-cert=client-cert.pem

--ssl-key=client-key.pem -h192.168.143.244 -udemo -pdemo -P3308



没有密钥文件是无法连接的,如上图所示。


登录进去后,输入status命令,可以看到已经使用SSL信息:



3、Sqlyog/Navicat客户端登录连接


由于我是用最新的OpenSSL,所以Sqlyog/Navicat客户端也需要下载最新版本,才可以验证通过。


Sqlyog连接:



Navicat连接:



注:打个广告,谁有Navicat for MySQL v11.2.16的注册码?


Step 8 - SSL加密验证


1、使用360开源的MySQL Sniffer工具嗅探


测试结果:DB开启了SSL,mysql-sniffer工具失效,无法探测到传输数据

视频地址:http://pan.baidu.com/s/1kVzAvK7


2、使用tcpdump工具嗅探


注:感谢DBA邱文辉协同测试


# tcpdump -i em2 port 3308 -l -s 0 -w - | strings > 1.txt


1)用未加密用户连接,脚本:


#!/bin/bash

while true

do

mysql -h192.168.143.244 -utest -ptest -P3308 -e   "select * from sbtest1 limit 5;"

sleep 1

done


测试结果:

# more 1.txt(可以看到是明文传输的)



2)用SSL加密用户连接


测试结果:

# more 2.txt(可以看到是数据已经是乱码了,加密成功)



四、演示视频


云盘链接:http://pan.baidu.com/s/1kVzAvK7


相关专题:

 

精选专题(官网:dbaplus.cn)

◆  近期热文  ◆  

10款常见MySQL高可用方案选型解读

基于Docker的DevOps实现

深入浅出XTTS:Oracle数据库迁移升级利器

京东MySQL数据库Docker化最佳实践

性能优化利器:数据库审核平台的选型与实践


◆  MVP专栏  ◆  

杨志洪杨建荣邹德裕韩锋欧阳辰

网易腾讯云百度朱祥磊卢钧轶

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存